package com.topisv.tms.web;

import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;

import net.sf.json.JSONObject;
import net.ytoec.kernel.response.mailnoresponse.MailNoResponse;

import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;

import com.google.common.collect.Maps;
import com.taobao.api.domain.WaybillAddress;
import com.taobao.api.domain.WaybillApplySubscriptionInfo;
import com.taobao.api.domain.WaybillBranchAccount;
import com.taobao.api.response.WlbWaybillISearchResponse;
import com.topisv.tms.entity.AreaGroup;
import com.topisv.tms.entity.ExpressConfigure;
import com.topisv.tms.entity.JSONParam;
import com.topisv.tms.entity.LogisticsCompany;
import com.topisv.tms.entity.ProcessLog;
import com.topisv.tms.entity.QueryParamHolder;
import com.topisv.tms.entity.ShopSource;
import com.topisv.tms.entity.ViewLogisticsCompanyNO;
import com.topisv.tms.repository.ProcessLogDao;
import com.topisv.tms.service.AreaGroupService;
import com.topisv.tms.service.ExpressConfigureService;
import com.topisv.tms.service.ExpressStyleService;
import com.topisv.tms.service.LogisticsCompanyService;
import com.topisv.tms.service.LogisticsMailNoService;
import com.topisv.tms.service.ShopSourceService;
import com.topisv.tms.service.ViewLogisticsCompanyServics;
import com.topisv.tms.service.vo.CNCompanyInfo;
import com.topisv.tms.utils.WmsContants;
import com.topisv.tms.utils.enums.StatusEnums;
import com.topisv.tms.utils.sto.MailSTOUtil;
import com.topisv.tms.utils.taobao.TopClientUtils;
import com.topisv.tms.utils.ttkd.DayMailSendRequest;
import com.topisv.tms.utils.yto.YTOMailNo;
import com.topisv.tms.web.base.BaseDataTableController;

@Controller
@RequestMapping(value = "/v2/logistics")
public class LogisticsCompanyController extends BaseDataTableController{
	private static Map<String, String> sortTypes = Maps.newLinkedHashMap();
	static {
		sortTypes.put("companyName", "名称");
		sortTypes.put("companyCode", "编码");
	}

	@Autowired
	private LogisticsCompanyService logisticsCompanyService;
	@Autowired
	private ExpressStyleService expressStyleService;
	@Autowired
	private ViewLogisticsCompanyServics viewLogisticsCompanyService;
	@Autowired
	private AreaGroupService areagroupService;
	@Autowired
	private LogisticsMailNoService logisticsMailNoService;
	@Autowired
	private ExpressConfigureService expressConfigureService;
	@Autowired
	private ShopSourceService shopSourceService;
	
	@Autowired
	private ProcessLogDao processLogDao;
	@RequestMapping(value = "v2_list")
	public String list() {
		return "logistics/logisticsList";
	}

	@RequestMapping(value = "page")
	public void page(@RequestBody JSONParam[] paramJson, HttpServletRequest request,HttpServletResponse response){
		try {
			// 客户端参数
			QueryParamHolder paramHolder = collectParam(paramJson);
			Page<LogisticsCompany> page = logisticsCompanyService.getLogisticsCompany(paramHolder);
			// 封装查询结果
			response.getWriter().print(bulidJSON(page));
		} catch (Exception e) {
			
		}
	}

	@RequestMapping(value = "create", method = RequestMethod.GET)
	public String createForm(Model model) {
		model.addAttribute("logistics", new LogisticsCompany());
		model.addAttribute("action", "create");
		model.addAttribute("titlePage", "增加物流公司");
		model.addAttribute("status", "0");
		return "logistics/logisticsForm";
	}

	@RequestMapping(value = "create", method = RequestMethod.POST)
	public String create(@Valid LogisticsCompany newLogisticsCompany,
			BindingResult result, Model model,
			RedirectAttributes redirectAttributes) {
		if (result.hasErrors()) {
			model.addAttribute("logistics", new LogisticsCompany());
			model.addAttribute("errors", result.getFieldErrors());
			// model.addAttribute("errors", result);
			model.addAttribute("action", "create");
			return "logistics/logisticsForm";
		}
		logisticsCompanyService.addLogisticsCompany(newLogisticsCompany);
		redirectAttributes.addFlashAttribute("message", "增加成功");
		return "redirect:/v2/logistics/v2_list";
	}

	@RequestMapping(value = "update/{id}", method = RequestMethod.GET)
	public String updateForm(@PathVariable("id") Long id, Model model) {
		model.addAttribute("logistics", logisticsCompanyService.getLogisticsCompany(id));
		model.addAttribute("action", "update");
		model.addAttribute("titlePage", "修改物流公司");
		model.addAttribute("status", "1");
		return "logistics/logisticsForm";
	}

	@RequestMapping(value = "update", method = RequestMethod.POST)
	public String update(
			@Valid @ModelAttribute("preloadTask") LogisticsCompany newLogisticsCompany,
			RedirectAttributes redirectAttributes) {
		logisticsCompanyService.addLogisticsCompany(newLogisticsCompany);
		redirectAttributes.addFlashAttribute("message", "更新成功");
		return "redirect:/v2/logistics/v2_list";
	}

	@RequestMapping(value = "delete/{id}")
	public String delete(@PathVariable("id") Long id,
			RedirectAttributes redirectAttributes) {
		logisticsCompanyService.deleteLogisticsCompany(id);
		expressStyleService.deleteLogisticsId(id);
		redirectAttributes.addFlashAttribute("message", "删除成功");
		return "redirect:/v2/logistics/v2_list";
	}

	
	/**
	 * 使用@ModelAttribute, 实现Struts2
	 * Preparable二次部分绑定的效果,先根据form的id从数据库查出Task对象,再把Form提交的内容绑定到该对象上。
	 * 因为仅update()方法的form中有id属性，因此本方法在该方法中执行.
	 */
	@ModelAttribute("preloadTask")
	public LogisticsCompany getTask(
			@RequestParam(value = "id", required = false) Long id) {
		if (id != null) {
			return logisticsCompanyService.getLogisticsCompany(id);
		}
		return null;
	}
	
	@RequestMapping(value="logisticsMailNoList")
	public String LogisticsMailNo(Model model){
		List<LogisticsCompany> company = logisticsCompanyService.findCompanyNameAndCode();
		model.addAttribute("company",company);
		fillSelectValue(model, null);
		List<AreaGroup> warehouseList = null;
		warehouseList = areagroupService.loadByWarehouseType(StatusEnums.user_type_paiu.getStatus());
		model.addAttribute("warehouseList", warehouseList);
		return "logistics/logisticsMailNo";
	}
	
	@RequestMapping(value="findLogistics")
	public void findLogisticsByCode(@RequestBody JSONParam[] paramJson, HttpServletRequest request,HttpServletResponse response){
		try {
			// 客户端参数
			QueryParamHolder paramHolder = collectParam(paramJson);
			Page<ViewLogisticsCompanyNO> page = viewLogisticsCompanyService.findMailNoByCompanyCode(paramHolder);
			// 封装查询结果
			response.getWriter().print(bulidJSON(page));
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	@RequestMapping(value = "cnInfo")
	public String findCNInfo(Model model,@RequestParam(value = "companyCode",required=false) String companyCode) {
		try {
			List<LogisticsCompany> company = logisticsCompanyService.findCompanyNameAndCode();
			model.addAttribute("company", company);
			
			if (!StringUtils.isBlank(companyCode)) {
				ShopSource shopSource = shopSourceService.findByShopCode(WmsContants.SHOP_CODE_CN);
				WlbWaybillISearchResponse waybillISearchResponse = TopClientUtils.topSearchByCpCode(companyCode, shopSource.getTopisvSessionKey());
				if(!StringUtils.isBlank(waybillISearchResponse.getErrorCode())){
					log.error("{}|{}|{}|{}",waybillISearchResponse.getErrorCode(),waybillISearchResponse.getMsg(),waybillISearchResponse.getSubCode(),waybillISearchResponse.getSubMsg());
				} else {
					List<WaybillApplySubscriptionInfo> subscribtions = waybillISearchResponse.getSubscribtions();
					if(subscribtions != null){
						List<CNCompanyInfo> infos = new ArrayList<CNCompanyInfo>();
						for (WaybillApplySubscriptionInfo subscriptionInfo : subscribtions) {
							for (WaybillBranchAccount account : subscriptionInfo.getBranchAccountCols()) {
								CNCompanyInfo cnInfo = new CNCompanyInfo();
								cnInfo.setCpType(subscriptionInfo.getCpType());
								cnInfo.setCpCode(subscriptionInfo.getCpCode());
								cnInfo.setAllocatedQuantity(account.getAllocatedQuantity());
								cnInfo.setCancelQuantity(account.getCancelQuantity());
								cnInfo.setPrintQuantity(account.getPrintQuantity());
								cnInfo.setQuantity(account.getQuantity());
								cnInfo.setBranchCode(account.getBranchCode());
								cnInfo.setBranchName(account.getBranchName());
								List<WaybillAddress> addressCols = account.getShippAddressCols();
								StringBuilder sb = new StringBuilder();
								for (WaybillAddress waybillAddress : addressCols) {
									sb.append(waybillAddress.getProvince()).append(waybillAddress.getCity()).append(waybillAddress.getArea()).append(waybillAddress.getAddressDetail());
									sb.append("\n");
								}
								cnInfo.setAddress(sb.toString());
								infos.add(cnInfo);
							}
							model.addAttribute("cnInfos", infos);
						}
					}
				}
			}
			return "logistics/logisticsMailNoCN";
		} catch (Exception e) {
			log.error("error", e);
		}
		return null;
	}
	/**
	 * 申领面单号
	 * @param areaGroupCode
	 * @param companyCode
	 * @param request
	 * @param response
	 */
	@RequestMapping(value = "ajaxMailNoRequest", method = RequestMethod.POST)
	public void ajaxUpdateBox(
			@RequestParam(value = "areaGroupCode") String areaGroupCode,
			@RequestParam(value = "companyCode") String companyCode,
			HttpServletRequest request, HttpServletResponse response) {
		PrintWriter out = null;
		JSONObject json = null;
		try {
			out = response.getWriter();
			json = new JSONObject();
			ExpressConfigure expressConfigure = expressConfigureService.findByWarehouseAndCompany(areaGroupCode, companyCode);
			if("STO".equals(companyCode)){
				List<String> mailNos = MailSTOUtil.mailNoRequest(expressConfigure);
				if(mailNos==null){
					json.put("status", "0");
					json.put("content", "申领失败，请稍后重试");
					out.print(json.toString());
					return ;
				}
				List<String> lms=logisticsMailNoService.save(mailNos, areaGroupCode, companyCode,"");
				json.put("status", "1");
				json.put("content", lms.size());
				ProcessLog Plog = new ProcessLog("AddMailno","仓库"+areaGroupCode+"申领"+companyCode+"号段,共"+lms.size()+"条");
				processLogDao.save(Plog);
				out.print(json.toString());
			}else if("YTO".equals(companyCode)){
				MailNoResponse mailNoResponse = YTOMailNo.mailNoRequest(expressConfigure);
				if(mailNoResponse==null){
					json.put("status", "0");
					json.put("content", "申领失败，请稍后重试");
					out.print(json.toString());
					return ;
				}
				if(!mailNoResponse.getSuccess()){
					json.put("status", "0");
					json.put("content", mailNoResponse.getMessage());
					out.print(json.toString());
					return ;
				}
				List<String> mailNos=mailNoResponse.getMailNoList();
				List<String> lms=logisticsMailNoService.save(mailNos, areaGroupCode, companyCode,mailNoResponse.getSequence());
				json.put("status", "1");
				json.put("content", lms.size());
				ProcessLog Plog = new ProcessLog("AddMailno","仓库"+areaGroupCode+"申领"+companyCode+"号段,Sequence="+mailNoResponse.getSequence()+",共"+lms.size()+"条");
				processLogDao.save(Plog);
				out.print(json.toString());
			} else if("TTKDEX".equals(companyCode)) {
				List<String> mailNos = DayMailSendRequest.SendWayBillMessage(expressConfigure);
				if(mailNos==null || mailNos.isEmpty()){
					json.put("status", "0");
					json.put("content", "申领失败，请稍后重试");
					out.print(json.toString());
					return ;
				}
				List<String> lms=logisticsMailNoService.save(mailNos, areaGroupCode, companyCode,"");
				json.put("status", "1");
				json.put("content", lms.size());
				ProcessLog Plog = new ProcessLog("AddMailno","仓库"+areaGroupCode+"申领"+companyCode+"号段,共"+lms.size()+"条");
				processLogDao.save(Plog);
				out.print(json.toString());
			}
			
		} catch (Exception e) {
			json.put("status", "0");
			json.put("content", e.getMessage());
			out.print(json.toString());
			log.error("error", e);
		}
	}
	
	@RequestMapping(value = "addMailNo", method = RequestMethod.POST)
	public void addMailNo(
			@RequestParam(value = "areaGroupCode") String areaGroupCode,
			@RequestParam(value = "companyCode") String companyCode,
			@RequestParam(value = "from_number") String from_number,
			@RequestParam(value = "to_number") String to_number,
			@RequestParam(value = "sequence") String sequence,
			ServletRequest request,ServletResponse response){
		PrintWriter out = null;
		JSONObject json = null;
		try {
			out = response.getWriter();
			json = new JSONObject();
			Long fromNum = Long.parseLong(from_number);
			Long toNum = Long.parseLong(to_number);
			List<String> mailNos = new ArrayList<String>();
			for(Long i = fromNum;i<=toNum;i++){
				mailNos.add(i+"");
			}
			List<String> lms=logisticsMailNoService.save(mailNos, areaGroupCode, companyCode,sequence);
			json.put("status", "1");
			json.put("content", lms.size());
			ProcessLog Plog = new ProcessLog("AddMailno","仓库"+areaGroupCode+"添加"+companyCode+"号段："+from_number+"-"+to_number+",共"+lms.size()+"条");
			processLogDao.save(Plog);
			out.print(json.toString());
		} catch (Exception e) {
			log.error("error", e);
		}
	}
}
